home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / gfx / show / gs_src_gs.lha / gs5.03 / smtf.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  4KB  |  167 lines

  1. /* Copyright (C) 1995, 1996 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* smtf.c */
  20. /* MoveToFront filters */
  21. #include "stdio_.h"
  22. #include "strimpl.h"
  23. #include "smtf.h"
  24.  
  25. /* ------ MoveToFrontEncode/Decode ------ */
  26.  
  27. private_st_MTF_state();
  28.  
  29. #define ss ((stream_MTF_state *)st)
  30.  
  31. /* Initialize */
  32. private int
  33. s_MTF_init(stream_state *st)
  34. {    int i;
  35.     for ( i = 0; i < 256; i++ )
  36.       ss->prev.b[i] = (byte)i;
  37.     return 0;
  38. }
  39.  
  40. /* Encode a buffer */
  41. private int
  42. s_MTFE_process(stream_state *st, stream_cursor_read *pr,
  43.   stream_cursor_write *pw, bool last)
  44. {    register const byte *p = pr->ptr;
  45.     register byte *q = pw->ptr;
  46.     const byte *rlimit = pr->limit;
  47.     uint count = rlimit - p;
  48.     uint wcount = pw->limit - q;
  49.     int status =
  50.         (count < wcount ? 0 :
  51.          (rlimit = p + wcount, 1));
  52.     while ( p < rlimit )
  53.     {    byte b = *++p;
  54.         int i;
  55.         byte prev = b, repl;
  56.         for ( i = 0; (repl = ss->prev.b[i]) != b; i++ )
  57.           ss->prev.b[i] = prev, prev = repl;
  58.         ss->prev.b[i] = prev;
  59.         *++q = (byte)i;
  60.     }
  61.     pr->ptr = p;
  62.     pw->ptr = q;
  63.     return status;
  64. }
  65.  
  66. /* Stream template */
  67. const stream_template s_MTFE_template =
  68. {    &st_MTF_state, s_MTF_init, s_MTFE_process, 1, 1
  69. };
  70.  
  71. /* Decode a buffer */
  72. private int
  73. s_MTFD_process(stream_state *st, stream_cursor_read *pr,
  74.   stream_cursor_write *pw, bool last)
  75. {    register const byte *p = pr->ptr;
  76.     register byte *q = pw->ptr;
  77.     const byte *rlimit = pr->limit;
  78.     uint count = rlimit - p;
  79.     uint wcount = pw->limit - q;
  80.     int status = (count <= wcount ? 0 : (rlimit = p + wcount, 1));
  81.     /* Cache the first few entries in local variables. */
  82.     byte
  83.       v0 = ss->prev.b[0], v1 = ss->prev.b[1],
  84.       v2 = ss->prev.b[2], v3 = ss->prev.b[3];
  85.     while ( p < rlimit )
  86.     {    byte first;
  87.         /* Zeros far outnumber all other bytes in the BWBS */
  88.         /* code; check for them first. */
  89.         if ( *++p == 0 )
  90.           {    *++q = v0;
  91.             continue;
  92.           }
  93.         switch ( *p )
  94.         {
  95.         default:
  96.           {    uint b = *p;
  97.             byte *bp = &ss->prev.b[b];
  98.             *++q = first = *bp;
  99. #if arch_sizeof_long == 4
  100.             ss->prev.b[3] = v3;
  101. #endif
  102.             /* Move trailing entries individually. */
  103.             for ( ; ; bp--, b-- )
  104.               {    *bp = bp[-1];
  105.                 if ( !(b & (sizeof(long) - 1)) )
  106.                   break;
  107.               }
  108.             /* Move in long-size chunks. */
  109.             for ( ; (b -= sizeof(long)) != 0; )
  110.               {    bp -= sizeof(long);
  111. #if arch_is_big_endian
  112.                 *(ulong *)bp =
  113.                   (*(ulong *)bp >> 8) |
  114.                   ((ulong)bp[-1] << ((sizeof(long) - 1) * 8));
  115. #else
  116.                 *(ulong *)bp = (*(ulong *)bp << 8) | bp[-1];
  117. #endif
  118.               }
  119.           }
  120. #if arch_sizeof_long > 4    /* better be 8! */
  121.             goto m7;
  122.         case 7:
  123.             *++q = first = ss->prev.b[7];
  124. m7:            ss->prev.b[7] = ss->prev.b[6];
  125.             goto m6;
  126.         case 6:
  127.             *++q = first = ss->prev.b[6];
  128. m6:            ss->prev.b[6] = ss->prev.b[5];
  129.             goto m5;
  130.         case 5:
  131.             *++q = first = ss->prev.b[5];
  132. m5:            ss->prev.b[5] = ss->prev.b[4];
  133.             goto m4;
  134.         case 4:
  135.             *++q = first = ss->prev.b[4];
  136. m4:            ss->prev.b[4] = v3;
  137. #endif
  138.             goto m3;
  139.         case 3:
  140.             *++q = first = v3;
  141. m3:            v3 = v2, v2 = v1, v1 = v0, v0 = first;
  142.             break;
  143.         case 2:
  144.             *++q = first = v2;
  145.             v2 = v1, v1 = v0, v0 = first;
  146.             break;
  147.         case 1:
  148.             *++q = first = v1;
  149.             v1 = v0, v0 = first;
  150.             break;
  151.         }
  152.     }
  153.     ss->prev.b[0] = v0;  ss->prev.b[1] = v1;
  154.     ss->prev.b[2] = v2;  ss->prev.b[3] = v3;
  155.     pr->ptr = p;
  156.     pw->ptr = q;
  157.     return status;
  158. }
  159.  
  160. /* Stream template */
  161. const stream_template s_MTFD_template =
  162. {    &st_MTF_state, s_MTF_init, s_MTFD_process, 1, 1,
  163.     NULL, NULL, s_MTF_init
  164. };
  165.  
  166. #undef ss
  167.